/**
 * @param {number} numCourses
 * @param {number[][]} prerequisites
 * @return {boolean}
 */
var canFinish = function (numCourses, prerequisites) {
  //定义邻接数组：每个节点 -> 该节点所有出度元素构成的数组（邻接元素）
  const adj = Array.from({ length: numCourses }, () => [])
  //定义入度数组：每个节点的入度个数
  const inDegree = new Array(numCourses).fill(0)
  //构建上面这两个数组
  for (const [course, pre] of prerequisites) {
    adj[pre].push(course)
    inDegree[course]++
  }

  //用数组模拟队列
  let queue = []
  //遍历数组inDegree：把入度为0的元素加入队列queue
  for (let i = 0; i < numCourses; i++) {
    if (inDegree[i] === 0) {
      queue.push(i)
    }
  }
  //处理过的节点数量
  let count = 0
  //队列非空时循环
  while (queue.length > 0) {
    //处理过的节点数量+1
    count++
    //将队首元素出列
    const course = queue.shift()
    //遍历队首元素的邻接表：邻接元素的入度-1，如果邻接元素的入度为0则入队
    for (const nextCourse of adj[course]) {
      inDegree[nextCourse]--
      if (inDegree[nextCourse] === 0) {
        queue.push(nextCourse)
      }
    }
  }

  return count === numCourses
};